﻿using FeiNuo.Core.Security;
using SmartCommunity.Models;
using Microsoft.EntityFrameworkCore;

namespace SmartCommunity.WebApi.Services
{
    public class UserService : BaseService, ILoginUserService
    {
        private readonly SCDBContext ctx;
        public UserService(SCDBContext ctx) { this.ctx = ctx; }

        #region 实现IUserDetailService，查询登录相关信息
        /// <summary>
        /// 登录时根据用户名查询用户信息:用户名/密码/角色/权限
        /// </summary>
        public async Task<LoginUser?> LoadUserByUsername(string username)
        {
            // 查询用户角色
            var user = await ctx.Users.Include(a => a.Roles).AsNoTracking()
                .Select(a => new
                {
                    a.UserId,
                    a.Nickname,
                    a.Avatar,
                    a.Username,
                    a.Password,
                    Roles = a.Roles.Select(r => new { r.RoleCode, r.RoleId })
                })
                .SingleOrDefaultAsync(a => a.Username == username);

            if (null == user) return null;

            // 角色/权限
            var roles = user.Roles.Select(a => a.RoleCode);
            var roleIds = user.Roles.Select(a => a.RoleId);
            var permissions = await ctx.Menus.AsNoTracking()
                .Where(m => m.Permission != "" && m.Roles.Any(r => roleIds.Contains(r.RoleId)))
                .Select(a => a.Permission)
                .ToListAsync();

            var data = user.UserId + "," + user.Nickname;

            // 返回用户信息
            return new LoginUser(user.Username, user.Password, roles, permissions, data);
        }


        /// <summary>
        /// 登录成功后，返回前端的用户信息
        /// </summary>
        public async Task<Dictionary<string, object>> GetLoginUserInfo(LoginUser user)
        {
            var map = new Dictionary<string, object>
            {
                { "username", user.Username },
                { "roles", user.Roles },
                { "permissions", user.Permissions },
            };
            var u = await ctx.Users.IgnoreAutoIncludes().AsNoTracking()
                .Select(a => new { a.UserId, a.Username, a.Nickname, a.Avatar })
                .SingleAsync(a => a.Username == user.Username);
            map.Add("nickname", u.Nickname);
            map.Add("avatar", u.Avatar ?? "");

            // 菜单一起返回，不再单独查一次
            var menuQuery = user.IsSuperAdmin
                ? ctx.Menus.AsQueryable()
                : ctx.Menus.Where(m => m.Roles.Any(r => user.Roles.Contains(r.RoleCode)));

            // 这里不加AsNoTracking,查出的结果会自动关联parent,children
            var menus = await menuQuery.OrderBy(m => m.SortNo).ToListAsync();

            // 转成路由
            var menuVOs = ConvertToMenuVO(menus.Where(a => a.Parent == null));
            // 添加固定的首页
            menuVOs.Insert(0, new MenuVO("首页", "/", "mdi-home"));
            map.Add("menus", menuVOs);

            return map;
        }
        private static List<MenuVO> ConvertToMenuVO(IEnumerable<MenuEntity> menus)
        {
            return menus.Where(a => a.MenuType != MenuType.Button).Select(a => new MenuVO(a.MenuName, a.MenuPath, a.Icon)
            {
                Children = ConvertToMenuVO(a.Children)
            }).ToList();
        }

        //private static List<RouteVO> ConvertMenuToRoute(IEnumerable<MenuEntity> menus)
        //{
        //    return menus.Select(a =>
        //    {
        //        var route = new RouteVO
        //        {
        //            Name = a.MenuType == MenuTypeEnum.Menu ? a.MenuPath.ToUpperFirst() : "",
        //            Component = a.Component ?? "",
        //            Path = a.MenuPath,
        //            //TODO 模块要不要加个redirect到具体的菜单
        //            Meta = new MetaVO(a.MenuName, a.Icon, a.Hidden, a.NoCache),
        //            Children = ConvertMenuToRoute(a.Children),
        //        };
        //        return route;
        //    }).ToList();
        //}
        #endregion
    }
}
